import { Game_Interpreter } from "@/objects/GameInterpreter.js";
import { Game_Enemy } from "@/objects/GameEnemy.js";
import { Game_Unit } from "@/objects/GameUnit.js";
import { contains } from "@/utils/Array.js";

export class Game_Troop extends Game_Unit {

    static LETTER_TABLE_HALF = [
    ' A',' B',' C',' D',' E',' F',' G',' H',' I',' J',' K',' L',' M',
    ' N',' O',' P',' Q',' R',' S',' T',' U',' V',' W',' X',' Y',' Z'
    ];
    static LETTER_TABLE_FULL = [
        'Ａ','Ｂ','Ｃ','Ｄ','Ｅ','Ｆ','Ｇ','Ｈ','Ｉ','Ｊ','Ｋ','Ｌ','Ｍ',
        'Ｎ','Ｏ','Ｐ','Ｑ','Ｒ','Ｓ','Ｔ','Ｕ','Ｖ','Ｗ','Ｘ','Ｙ','Ｚ'
    ];
    constructor() {
        super();
        this._interpreter = new Game_Interpreter();
        this.clear();
    }

    isEventRunning() {return this._interpreter.isRunning();}
    updateInterpreter() {this._interpreter.update();}
    turnCount() {return this._turnCount;}
    members() {return this._enemies;}

    clear() {
        this._interpreter.clear();
        this._troopId = 0;
        this._eventFlags = {};
        this._enemies = [];
        this._turnCount = 0;
        this._namesCount = {};
    }

    troop() {return $dataTroops[this._troopId];}

    setup(troopId) {
        this.clear();
        this._troopId = troopId;
        this._enemies = [];
        this.troop().members.forEach(member=>{
            if ($dataEnemies[member.enemyId]) {
                let enemyId = member.enemyId;
                let x = member.x;
                let y = member.y;
                let enemy = new Game_Enemy(enemyId, x, y);
                if (member.hidden) {
                    enemy.hide();
                }
                this._enemies.push(enemy);
            }
        });
        this.makeUniqueNames();
    }

    makeUniqueNames() {
        let table = this.letterTable();
        this.members().forEach(enemy=>{
            if (enemy.isAlive() && enemy.isLetterEmpty()) {
                let name = enemy.originalName();
                let n = this._namesCount[name] || 0;
                enemy.setLetter(table[n % table.length]);
                if(n>=1){enemy.setPlural(true);}
                this._namesCount[name] = n + 1;
            }
        });
    }

    letterTable() {
        return $gameSystem.isCJK() ? Game_Troop.LETTER_TABLE_FULL :
                Game_Troop.LETTER_TABLE_HALF;
    }

    enemyNames() {
        let names = [];
        this.members().forEach(function(enemy) {
            let name = enemy.originalName();
            if (enemy.isAlive() && !contains(names,name)) {
                names.push(name);
            }
        });
        return names;
    }

    meetsConditions(page) {
        let c = page.conditions;
        if (!c.turnEnding && !c.turnValid && !c.enemyValid &&
                !c.actorValid && !c.switchValid) {
            return false;  // Conditions not set
        }
        if (c.turnEnding) {
            if (!BattleManager.isTurnEnd()) {
                return false;
            }
        }
        if (c.turnValid) {
            let n = this._turnCount;
            let a = c.turnA;
            let b = c.turnB;
            if ((b === 0 && n !== a)) {
                return false;
            }
            if ((b > 0 && (n < 1 || n < a || n % b !== a % b))) {
                return false;
            }
        }
        if (c.enemyValid) {
            let enemy = $gameTroop.members()[c.enemyIndex];
            if (!enemy || enemy.hpRate() * 100 > c.enemyHp) {
                return false;
            }
        }
        if (c.actorValid) {
            let actor = $gameActors.actor(c.actorId);
            if (!actor || actor.hpRate() * 100 > c.actorHp) {
                return false;
            }
        }
        if (c.switchValid) {
            if (!$gameSwitches.value(c.switchId)) {
                return false;
            }
        }
        return true;
    }

    setupBattleEvent() {
        if (!this._interpreter.isRunning()) {
            if (this._interpreter.setupReservedCommonEvent()) {
                return;
            }
            let pages = this.troop().pages;
            for (let i = 0; i < pages.length; i++) {
                let page = pages[i];
                if (this.meetsConditions(page) && !this._eventFlags[i]) {
                    this._interpreter.setup(page.list);
                    if (page.span <= 1) {
                        this._eventFlags[i] = true;
                    }
                    break;
                }
            }
        }
    }

    increaseTurn() {
        let pages = this.troop().pages;
        for (let i = 0; i < pages.length; i++) {
            let page = pages[i];
            if (page.span === 1) {
                this._eventFlags[i] = false;
            }
        }
        this._turnCount++;
    }

    expTotal() {
        return this.deadMembers().reduce(function(r, enemy) {
            return r + enemy.exp();
        }, 0);
    }

    goldTotal() {
        return this.deadMembers().reduce(function(r, enemy) {
            return r + enemy.gold();
        }, 0) * this.goldRate();
    }

    goldRate() {
        return $gameParty.hasGoldDouble() ? 2 : 1;
    }

    makeDropItems() {
        return this.deadMembers().reduce(function(r, enemy) {
            return r.concat(enemy.makeDropItems());
        }, []);
    }
}

